#include "common.h"
#include "spawn_process.h"


process_t *child;
uv_stream_t *ssh;
uv_tty_t tty;

void on_read_child(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    ssh = stream;
    if (nread > 0) {
#if 0
        //printf("nread=%ld\n", nread);
        fwrite(buf->base, 1, nread, stdout);
        fflush(stdout);
#endif
        uv_write_t* req = (uv_write_t*)malloc(sizeof(uv_write_t));
        uv_buf_t b = uv_buf_init((char*)buf->base, nread);
        int r = uv_write(req, (uv_stream_t*)&tty, &b, 1, NULL);
        ASSERT_UV_OK(r);
    } else {
        //fprintf(stderr, "Read error: %s\n", uv_strerror(nread));
        uv_read_stop(stream);
    }
    free(buf->base);
}

void on_exit_child(uv_process_t *process, int64_t exit_status, int term_signal) {
    printf("Process exited with status %ld\n", exit_status);
    uv_close((uv_handle_t *)process, NULL);
}


/********************************************************************************/

void on_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    if (nread > 0) {
        if (buf->base[0] == 'Q') {
            printf("\n[exit]\n");
            uv_loop_t *loop = (uv_loop_t *)stream->data;
            uv_stop(loop);
        }

        uv_write_t* req = (uv_write_t*)malloc(sizeof(uv_write_t));
        //uv_buf_t b = {.base = buf->base, .len = nread};
        uv_buf_t b = uv_buf_init((char*)buf->base, nread);
        int r = uv_write(req, (uv_stream_t*)&child->in, &b, 1, NULL);
        ASSERT_UV_OK(r);

    } else if (nread < 0) {
        if (nread == UV_EOF) {
            printf("EOF reached\n");
        } else {
            fprintf(stderr, "Read error: %s\n", uv_strerror(nread));
        }
        uv_close((uv_handle_t *)stream, NULL);
    }
}

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
    buf->base = malloc(suggested_size);
    buf->len = suggested_size;
}

int main(int argc, char *argv[]) {
    uv_loop_t *loop = uv_default_loop();


    child = (process_t *)malloc(sizeof(process_t));
    if (!child) {
        fprintf(stderr, "Failed to allocate memory for process context\n");
        return 1;
    }

    child->on_read_stdout_cb = on_read_child;
    child->on_read_stderr_cb = on_read_child;
    child->on_exit_cb = on_exit_child;

    char *cmdline[] = {
        "ls",
        "-l",
        "xxx",
        NULL,
    };

    char *cmdline2[] = {
        //"ssh", "-t", "-t", "chongyu.guo@192.168.9.51",
        "ssh", "-t", "-t", "-t", "-t", "chongyu.guo@192.168.9.51",
        NULL,
    };

    process_init(loop, child, NULL, cmdline2);

    if (uv_tty_init(loop, &tty, 0, 1) != 0) {
        fprintf(stderr, "Failed to initialize TTY\n");
        return 1;
    }

    tty.data = loop;
    uv_tty_set_mode(&tty, UV_TTY_MODE_RAW);
    uv_read_start((uv_stream_t *)&tty, alloc_buffer, on_read);

    uv_run(loop, UV_RUN_DEFAULT);

    uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL);
    // uv_tty_reset_mode();
    uv_close((uv_handle_t *)&tty, NULL);

    uv_loop_close(loop);
    return 0;
}
